package cn.sccl.common.service.impl;

import cn.sccl.common.database.DataBase;
import cn.sccl.common.model.BaseModel;
import cn.sccl.common.model.PageResult;
import cn.sccl.common.dao.BaseDAO;
import cn.sccl.common.dao.impl.BaseQuery;
import cn.sccl.common.exception.BusinessException;
import cn.sccl.common.service.BaseManager;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Map;

/**
 * Created by 杨浩宇 on 2016-02-22.
 */
public abstract class BaseManagerImpl<T> implements BaseManager<T> {

    protected Log log = LogFactory.getLog(getClass());
    @Autowired
    private DataBase dataBase;

    public abstract BaseDAO<T> getBaseDAO();

    public DataBase getDataBase() {
        return this.dataBase;
    }

    @Override
    public T get(String id) {
        return getBaseDAO().get(id);
    }

    @Override
    public List<T> gets(List<String> ids) {
        return getBaseDAO().gets(ids);
    }

    @Override
    public void create(T model) {
        Object primaryKeyValue = null;
        if (model instanceof BaseModel) {
            primaryKeyValue = ((BaseModel) model).getId();
        } else {
            try {
                primaryKeyValue = PropertyUtils.getProperty(model, getBaseDAO().getPrimaryKeyName());
            } catch (Exception e) {
                e.printStackTrace();
                throw new BusinessException("保存对象【" + model.getClass().getName() + "】失败！", e.getCause());
            }
        }
        if (primaryKeyValue == null) {
            getBaseDAO().insert(model);
        } else {
            getBaseDAO().insertWithPrimaryKey(model);
        }
    }

    @Override
    public void update(T model) {
        this.update(model, false);
    }

    @Override
    public void update(T model, boolean isupdateMC) {
        this.getBaseDAO().update(model, isupdateMC);
    }

    @Override
    public void save(T model) {
        this.save(model, false);
    }

    @Override
    public void save(T model, boolean isupdateMC) {
        this.getBaseDAO().save(model, isupdateMC);
    }

    @Override
    public List<T> listAll() {
        return getBaseDAO().listAll();
    }

    @Override
    public List<T> query(BaseQuery query) {
        return getBaseDAO().query(query);
    }

    @Override
    public void delete(String id) {
        this.getBaseDAO().delete(id);
    }


    @Override
    public void deleteBatch(List<T> list) {
        if (list == null || list.size() == 0)
            return;
        for (T t : list) {
            delete(((BaseModel) t).getId());
        }
    }

    @Override
    public void deleteBatch(String[] idArr) {
        if (idArr == null || idArr.length == 0)
            return;
        for (String t : idArr) {
            delete(t);
        }
    }

    @Override
    public List<T> findBy(Map<String, Object> map) {
        return getBaseDAO().findBy(map);
    }

    @Override
    public List<T> findByLike(Map<String, Object> map) {
        return getBaseDAO().findByLike(map);
    }

    @Override
    public T findUniqueBy(Map<String, Object> map) {
        return getBaseDAO().findUniqueBy(map);
    }

    @Override
    public void updatePartialModel(T objModel) {
        this.getBaseDAO().updatePartialModel(objModel);
    }

    @Override
    public void updatePartialModel(T o, String[] aryNullFields) {
        this.getBaseDAO().updatePartialModel(o, aryNullFields);
    }

    @Override
    public Map<String, T> findMapBy(String key, Map<String, Object> map) {
        return getBaseDAO().findMapBy(key, map);
    }

    @Override
    public Map<String, T> findMapByLike(String key, Map<String, Object> map) {
        return getBaseDAO().findMapByLike(key, map);
    }

    @Override
    public void saveBatch(List<T> modelList) {
        saveBatch(modelList, false);
    }

    @Override
    public void saveBatch(List<T> modelList, boolean isupdateMC) {
        if (CollectionUtils.isNotEmpty(modelList)) {
            for (T t : modelList) {
                this.save(t, isupdateMC);
            }
        }
    }

    @Override
    public void savePartialBatch(List<T> modelList) {
        savePartialBatch(modelList, false);
    }

    @Override
    public void savePartialBatch(List<T> modelList, boolean isupdateMC) {
        if (CollectionUtils.isNotEmpty(modelList)) {
            for (T t : modelList) {
                this.getBaseDAO().updatePartialModel(t);
            }
        }
    }

    /**
     * 分页查询，所有条件要求满足完全匹配，即where语句不会应用like条件
     *
     * @param pageIndex 页码
     * @param pageSize  分页大小
     * @param params
     * @return
     */
    @Override
    public PageResult<T> pageQuery(long pageIndex, int pageSize, Map<String, Object> params) {
        return getBaseDAO().pageQuery(pageIndex, pageSize, params);
    }

    /**
     * 分页查询，字符串属性在where语句应用like条件
     *
     * @param pageIndex 页码
     * @param pageSize  分页大小
     * @param params
     * @return
     */
    @Override
    public PageResult<T> pageQueryByLike(long pageIndex, int pageSize, Map<String, Object> params) {
        return getBaseDAO().pageQueryByLike(pageIndex, pageSize, params);
    }
}
